package com.qiangesoft.pay.service.impl;

import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConfig;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.qiangesoft.pay.config.WxpayProperties;
import com.qiangesoft.pay.service.PayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信支付
 *
 * @author qiangesoft
 * @date 2024-02-23
 */
@Service
public class WxpayServiceImpl implements PayService {

    @Autowired
    private WxpayProperties wxpayProperties;

    @Override
    public String pay(String orderNo, String subject, BigDecimal amount) {
        try {
            WXPay wxpay = new WXPay(new WXPayConfig() {
                @Override
                public String getAppID() {
                    return wxpayProperties.getAppId();
                }

                @Override
                public String getMchID() {
                    return wxpayProperties.getMchId();
                }

                @Override
                public String getKey() {
                    return wxpayProperties.getKey();
                }

                @Override
                public InputStream getCertStream() {
                    try {
                        return new FileInputStream(wxpayProperties.getCertPath());
                    } catch (FileNotFoundException e) {
                        throw new RuntimeException(e);
                    }
                }

                @Override
                public int getHttpConnectTimeoutMs() {
                    return 0;
                }

                @Override
                public int getHttpReadTimeoutMs() {
                    return 0;
                }

            }, WXPayConstants.SignType.MD5);
            Map<String, String> data = new HashMap<>();
            data.put("body", subject);
            data.put("out_trade_no", orderNo);
            data.put("fee_type", "CNY");
            data.put("total_fee", String.valueOf(amount.multiply(new BigDecimal(100)).intValue()));
            data.put("spbill_create_ip", "127.0.0.1");
            data.put("notify_url", wxpayProperties.getNotifyUrl());
            data.put("trade_type", wxpayProperties.getTradeType());
            // 发起支付请求
            Map<String, String> resp = wxpay.unifiedOrder(data);
            if ("SUCCESS".equals(resp.get("return_code")) && "SUCCESS".equals(resp.get("result_code"))) {
                return resp.get("code_url");
            } else {
                throw new RuntimeException("wxpay error");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String notify(HttpServletRequest request) {
        try {
            // 解析微信支付回调请求参数
            InputStream inputStream = request.getInputStream();
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, length);
            }
            String xml = outputStream.toString("utf-8");
            Map<String, String> params = WXPayUtil.xmlToMap(xml);
            // 验证微信支付
            WXPay wxpay = new WXPay(new WXPayConfig() {
                @Override
                public String getAppID() {
                    return wxpayProperties.getAppId();
                }

                @Override
                public String getMchID() {
                    return wxpayProperties.getMchId();
                }

                @Override
                public String getKey() {
                    return wxpayProperties.getKey();
                }

                @Override
                public InputStream getCertStream() {
                    try {
                        return new FileInputStream(wxpayProperties.getCertPath());
                    } catch (FileNotFoundException e) {
                        throw new RuntimeException(e);
                    }
                }

                @Override
                public int getHttpConnectTimeoutMs() {
                    return 0;
                }

                @Override
                public int getHttpReadTimeoutMs() {
                    return 0;
                }

            }, WXPayConstants.SignType.MD5);
            boolean verifyResult = wxpay.isPayResultNotifySignatureValid(params);
            if (verifyResult) {
                // 处理微信支付回调请求
                String outTradeNo = params.get("out_trade_no");
                String transactionId = params.get("transaction_id");
                String totalFee = params.get("total_fee");
                // todo 更新订单支付成功
                return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
            } else {
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名验证失败]]></return_msg></xml>";
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

